/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.gobygang.server;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.gobygang.shared.AwardInfo;
import com.gobygang.shared.LoginInfo;
import com.gobygang.shared.TaxiGanguserInfo;
import com.gobygang.shared.TaxiGanguserInfo.Status;
import com.google.appengine.api.datastore.Key;

/**
 *
 * @author pd200508
 */
@Entity
@Table(name = "TAXIGANGUSER")
@NamedQueries({@NamedQuery(name = "TaxiGanguser.findByTaxiGanguserid", query = "SELECT a FROM TaxiGanguser a WHERE a.key = :key"), 
	@NamedQuery(	name = "TaxiGanguser.findAll", 				query = "SELECT a FROM TaxiGanguser a "),
	@NamedQuery(	name = "TaxiGanguser.findById", 				query = "SELECT a FROM TaxiGanguser a WHERE a.id = :id"),
	@NamedQuery(	name = "TaxiGanguser.findByTemporaryUsername", 	query = "SELECT a FROM TaxiGanguser a WHERE a.temporaryusername = :temporaryusername AND a.temporary = TRUE"),	
	@NamedQuery(name = "TaxiGanguser.findByFirstname", query = "SELECT a FROM TaxiGanguser a WHERE a.firstname = :firstname"), 
	@NamedQuery(name = "TaxiGanguser.findByLastname", query = "SELECT a FROM TaxiGanguser a WHERE a.lastname = :lastname"), 
	@NamedQuery(name = "TaxiGanguser.findByDisplayname", query = "SELECT a FROM TaxiGanguser a WHERE a.displayname = :displayname"), 
	@NamedQuery(name = "TaxiGanguser.findByPassword", query = "SELECT a FROM TaxiGanguser a WHERE a.password = :password"), 
	@NamedQuery(name = "TaxiGanguser.findByGroups", query = "SELECT a FROM TaxiGanguser a WHERE a.groups = :groups"), 
	@NamedQuery(name = "TaxiGanguser.findByPhone", query = "SELECT a FROM TaxiGanguser a WHERE a.phone = :phone"), 
	@NamedQuery(name = "TaxiGanguser.findByEmail", query = "SELECT a FROM TaxiGanguser a WHERE a.email = :email")
	})
	public class TaxiGanguser implements Serializable {

	public static final  String DISPLAYNAME="DISPLAYNAME";

	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "KEY", nullable = false)
	private Key key;
	@Column(name = "ID", nullable = false)
	private String id;
	private String temporaryusername;
	private String temporarypassword;
	private Boolean temporary;
	private Status status;
	//    @Column(name = "FIRSTNAME")
	//    private String firstname;
	//    @Column(name = "LASTNAME")
	//    private String lastname;
	@Column(name = DISPLAYNAME, nullable = false)
	private String displayname;
	//    @Column(name = "PASSWORD")
	//    private String password;
	//    @Column(name = "GROUPS")
	//    private String groups;
	//    @Column(name = "PHONE")
	//    private String phone;
	@Column(name = "EMAIL")
	private String email;
	@Column(name = "CITIES", nullable = true)
	private List<String>  cityList;
	@Column(name = "ADDRESSES", nullable = true)
	private List<String> addressList;
	@Column(name = "POINTS", nullable = true)
	private Integer points;
	//    @OneToMany(mappedBy = "taxiganguserTaxiGanguserid", cascade=CascadeType.ALL)
	//    private Collection<Bid> bidCollection;
	//    @OneToMany(mappedBy = "taxiganguserTaxiGanguserid", cascade=CascadeType.ALL)
	//    private Collection<TaxiGang> taxigangCollection;
	//    @JoinColumn(name = "ADDRESSEJB_ADDRESSID", referencedColumnName = "ADDRESSID")
	//    @ManyToOne (cascade=CascadeType.ALL)
	//    private Address addressAddressid;
	//    @JoinColumn(name = "CREDITCARDEJB_CREDITCARDID", referencedColumnName = "CREDITCARDID")
	//    @ManyToOne(cascade=CascadeType.ALL)
	//    private Creditcard creditcardCreditcardid;

    @ManyToOne(fetch = FetchType.LAZY)
    private TaxiGang taxiGang;

	@Column(name = "MYTAXIGANGS", nullable = true)
	@OneToMany(cascade = CascadeType.ALL)
	private ArrayList<Long> myTaxigangs = new ArrayList<Long>();

	@Column(name = "AWARDS", nullable = true)
	@OneToMany(cascade = CascadeType.ALL)
	private ArrayList<Award> awards = new ArrayList<Award>();
	public TaxiGanguser() {
	}
	public TaxiGanguser(LoginInfo info) {
		displayname = info.getNickname();
		temporary = info.getIsTempory();
		if (temporary){
			temporaryusername = info.getTemporyUserName();
			temporarypassword = info.getTemporyPassword();
			displayname = info.getTemporyUserName();
			id = info.getTemporyUserName()+Math.random();
		} else {
			id = info.getId();
		}
	}

	public TaxiGanguserInfo getInfo(){
		
		TaxiGanguserInfo taxiGanguserInfo = new TaxiGanguserInfo();
		taxiGanguserInfo.setId(id);
		taxiGanguserInfo.setDisplayName(displayname);
		taxiGanguserInfo.setCityList(getCityList().toArray(new String[0]));
		taxiGanguserInfo.setAddressList(getAddressList().toArray(new String[0]));
		
		taxiGanguserInfo.setStatus(status);
		if (points != null){
		taxiGanguserInfo.setPoints(points);
		} else {
			taxiGanguserInfo.setPoints(0);
		}
		
		if (awards.size()==0){
			AwardInfo[] awardInfos = new AwardInfo[1];
			AwardInfo awardInfo = new AwardInfo();
			awardInfo.setPoints(0);
			awardInfo.setAwardText("Not rated yet");
			awardInfos[0]=awardInfo;
			taxiGanguserInfo.setAwards(awardInfos);
			
		} else {
			AwardInfo[] awardInfos = new AwardInfo[awards.size()];
			int i =0;
			for (Award award : awards){
				AwardInfo awardInfo = award.getInfo();
				awardInfos[i++]=awardInfo;
			}
			taxiGanguserInfo.setAwards(awardInfos);
			
		}
		
		
		return taxiGanguserInfo;
	}

	public void setInfo(TaxiGanguserInfo taxiGanguserInfo){
		//merge with info
		for (String city : taxiGanguserInfo.getCityList()){
			if (!getCityList().contains(city)){
				getCityList().add(city);
			}
		}
		for (String address : taxiGanguserInfo.getAddressList()){
			if (!getAddressList().contains(address)){
				getAddressList().add(address);
			}
		}
	}

	public List<String> getCityList() {
		if (cityList == null){
			cityList = new ArrayList<String>();
		}
		return cityList;
	}

	public List<String> getAddressList() {
		if (addressList == null){
			addressList = new ArrayList<String>();
		}
		return addressList;
	}

	public void setCityList(List<String> l) {
		cityList=l;
	}
	public void setAddressList(List<String> l) {
		addressList=l;
	}
//	public void updateAddressHistory(TaxiGangInfo taxiGangInfo) {
//		for (String city : new String[] {taxiGangInfo.getStart(), taxiGangInfo.getDestinationCity()}){
//			if (!getCityList().contains(city) && city != null){
//				getCityList().add(city);
//			}
//		}
//		for (String address : new String[] {taxiGangInfo.getStartAddress(), taxiGangInfo.getDestinationAddress()}){
//			if (!getAddressList().contains(address) && address != null){
//				getAddressList().add(address);
//			}
//		}
//	}

	public void mergeCityHistory(List<String>cityList) {
		for (String city : cityList){
			if (!getCityList().contains(city) && city != null){
				getCityList().add(city);
			}
		}
	}

	public void mergeAddressHistory(List<String>addessList) {
		for (String address : addessList){
			if (!getAddressList().contains(address) && address != null){
				getAddressList().add(address);
			}
		}
	}

	public Key getKey() {
		return key;
	}

	public long getId() {
		return key.getId();
	}

	public String getDisplayname() {
		return displayname;
	}

	public void setDisplayname(String displayname) {
		//Log.info("TaxiGang:setDisplayname"+displayname);
		if (displayname == null){
			displayname = "n.k.";
		}
		this.displayname = displayname;
	}


	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		this.status = status;
	}

	public String getTemporaryPassword() {
		return temporarypassword;
	}

	public void addTaxigang(long taxiGangId) {
		if (!myTaxigangs.contains(taxiGangId)){
			myTaxigangs.add(taxiGangId);
		}
	}

	public void removeTaxigang(long taxiGangId) {
		if (myTaxigangs.contains(taxiGangId)){
			myTaxigangs.remove(taxiGangId);
		}
	}

	public List<Long> getMyTaxiGangs(){
		return myTaxigangs;
	}

	@Override
	public int hashCode() {
		int hash = 0;
		hash += (key != null ? key.hashCode() : 0);
		return hash;
	}

	@Override
	public boolean equals(Object object) {
		// TODO: Warning - this method won't work in the case the id fields are not set
		if (!(object instanceof TaxiGanguser)) {
			return false;
		}
		TaxiGanguser other = (TaxiGanguser) object;
		if ((this.key == null && other.key != null) || (this.key != null && !this.key.equals(other.key))) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return "taxigangsystem.beans.TaxiGanguser[taxiganguserid=" + key.getId() + "]";
	}
	public void award(Award awarded) {
		awards.add(awarded);	
		if (points==null){
			points = 0;
		}
		points += awarded.getPoints();
	}

}
